package dao;

import java.io.Serializable;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Required;

public abstract class AbstractDAO<T extends Serializable> {

	private SessionFactory sessionFactory;

	public List<T> getAll() {
		StringBuilder queryBuilder = new StringBuilder().append("FROM ").append(getTabla());
		return queryListResult(queryBuilder.toString());
	}

	public T get(int id) {
		StringBuilder queryBuilder = new StringBuilder().append("FROM ").append(getTabla()).append(" table WHERE table.id = ").append(id);
		return (T) queryUniqueResult(queryBuilder.toString());
	}
	
	@SuppressWarnings("unchecked")
	public T save(T object) {
		Session session = obtainSession();
		T result = (T) session.save(object);
		finishSession(session);
		return result;
	}

	public Boolean delete(T object) {
		Session session = obtainSession();
		session.delete(object);
		finishSession(session);
		return true;
	}

	public T update(T object) {
		Session session = obtainSession();
		session.saveOrUpdate(object);
		finishSession(session);
		return object;
	}

	protected Session obtainSession() {
		return sessionFactory.openSession();
	}


	@Required
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	
	//---------------------------------------------Auxiliares---------------------------------------
	protected abstract String getTabla();
	
	private void finishSession(Session session) {
		session.flush();
		session.getTransaction().commit();
		session.close();
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> queryListResult(String query){
		Session session = obtainSession();
		return session.createQuery(query).list();
	}
	
	@SuppressWarnings("unchecked")
	protected T queryUniqueResult(String query){
		Session session = obtainSession();
		return (T) session.createQuery(query).uniqueResult();
	}
	
}
